package com.vmj.instructions.references;

import com.vmj.heap.VMClass;
import com.vmj.heap.ClassRef;
import com.vmj.heap.Constant;
import com.vmj.heap.RuntimeConstantPool;
import com.vmj.heap.VMObject;
import com.vmj.instructions.base.Index16Instruction;
import com.vmj.rtda.Frame;

/**
 * Created by yangshoujun on 2017/8/26 下午11:34.
 */
public class New extends Index16Instruction {

    @Override
    public void execute(Frame frame) {
        RuntimeConstantPool runtimeConstantPool = frame.getMethod().getClazz().getRuntimeConstantPool();
        Constant constant = runtimeConstantPool.getConstant(super.getIndex());
        ClassRef classRef = (ClassRef) constant.getValue();

        VMClass clazz = classRef.resolvedClass();
        if(!clazz.isInitStarted()) {
            frame.revertNextPc();
            VMClass.initClass(frame.getThread(), clazz);
            return;
        }

        if(clazz.isInterface() || clazz.isAbstract()) {
            throw new RuntimeException("java.lang.InstantiationError");
        }

        VMObject obj = clazz.instanciate();
        frame.getOperandStack().pushRef(obj);
    }
}
